import os

from django.shortcuts import render
from jwt import ExpiredSignatureError, DecodeError
from qiniu import Auth
from rest_framework.generics import ListAPIView, RetrieveUpdateDestroyAPIView, CreateAPIView
from rest_framework.response import Response

from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework_jwt.utils import jwt_decode_handler

from goods.serializers import *
from p6_421 import settings
from .models import *

class Page(PageNumberPagination):
    page_size_query_param = 'pagesize'
    page_query_param = 'page'  # 页码查询参数
    page_size = 3   #默认的每页展示数据条数

# 品牌的视图集
class BrandViewSet(ModelViewSet):
    queryset = Brand.objects.all()
    serializer_class = Brand_Serializer
    lookup_url_kwarg = 'pk'
    lookup_field = 'pk'

# 上传品牌logo
class UploadBrandLogo(APIView):
    def post(self, request):
        print('上传的图片数据:', request.data, type(request.data))
        #  获取文件对象
        file = request.data.get('file')
        # file.file 上传的文件字节流对象
        # file.name 文件名字
        # file_path 文件路径
        # 拼接路径
        static_path = 'static/images/logos'
        file_path = os.path.join(settings.BASE_DIR, static_path)
        file_name = os.path.join(file_path, file.name)

        #保存图片
        with open(file_name, 'wb') as f:
            f.write(file.file.read())

        data = {
            'static_path': static_path,
            'code': 200, 'msg': '上传图片成功'
        }
        return Response(data)


# 加载所有频道组数据
class ListChannels(ListAPIView):
    queryset = Group.objects.all()
    serializer_class = Group_Serializer

# 加载所有频道组数据
class ListCate(ListAPIView):
    queryset = Cate.objects.all()
    serializer_class = Cate_Serializer

# 检索 更新 删除 一个频道组数据
class ChannelInfo(RetrieveUpdateDestroyAPIView):
    queryset = Group.objects.all()
    serializer_class = Group_Serializer
    lookup_field = 'pk'
    lookup_url_kwarg = 'pk'


# 获取所有一级分类
class FirstCate(ListAPIView):
    queryset = Cate.objects.filter(cid=None)
    serializer_class = Cate_Serializer

# 添加频道组数据
class AddChannel(CreateAPIView):
    queryset = Group.objects.all()
    serializer_class = Group_Serializer

# SKU视图集
class SKUViewSet(ModelViewSet):
    queryset = Good.objects.all()
    serializer_class = Good_Serializer
    lookup_field = 'pk'
    lookup_url_kwarg = 'pk'
    pagination_class = Page


# 获取所有的SKU   不继承分页器
class SKUList(ListAPIView):
    queryset = Good.objects.all()
    serializer_class = Good_Serializer




# SPU视图集 SPUViewSet
class SPUViewSet(ModelViewSet):
    queryset = SPU.objects.all()
    serializer_class = SPU_Serializer
    lookup_field = 'pk'
    lookup_url_kwarg = 'pk'
    # pagination_class = Page

# 获取所有SPU
class ListSPUs(ListAPIView):
    queryset = SPU.objects.all()
    serializer_class = SPU_Serializer
    pagination_class = Page


# 加载所有的2,3子集类别
class SubCateApiView(APIView):
    def get(self, request, pk):

        # 查询当前的父级类别
        p_cate = Cate.objects.filter(id=pk).first()

        # 查询其自己类别
        subs = Cate.objects.filter(cid=p_cate)
        # subs = p_cate.subs.all()

        ser = Cate_Serializer(subs, many=True)

        # 3 返回响应
        return Response(ser.data)

# 规格名称视图集
class SPUSpecViewSet(ModelViewSet):
    queryset = SPUSpecification.objects.all()
    serializer_class = SPUSpecification_Serializer
    pagination_class = Page
# 获取全部规格名称
class ListSPUSpec(ListAPIView):
    queryset = SPUSpecification.objects.all()
    serializer_class = SPUSpecification_Serializer


# 规格选项视图集
class SpecOptionViewSet(ModelViewSet):
    queryset = SpecOption.objects.all()
    serializer_class = SpecOption_Serializer
    lookup_url_kwarg = 'pk'
    lookup_field = 'pk'
    pagination_class = Page


# 上传商品图片
class UploadSkuImageLogo(APIView):
    def post(self, request):
        print('上传商品的图片请求', request.data)

        # 1 直接获取上传的数据
        token = request.data.get('token')
            # 上传的文件对象file
        file = request.data.get('file')

        # 2 token验证
        try:
            payload = jwt_decode_handler(token)
        except ExpiredSignatureError:  # token过期
            return Response({'code': 401, 'msg': '口令过期'})
        except DecodeError:
            return Response({'code': 401, 'msg': '口令不正确'})

        # 3 用户已登录 可以正常上传图片
        file_name = file.name
        static_path = 'static/images/goods'
        abs_path = os.path.join(settings.BASE_DIR, static_path)

        # 4 判断目录是否存在 不存在创建   makedirs 创建多级目录
        if not os.path.exists(abs_path):
            os.makedirs(abs_path)

        # 5 拼接文件名 打开并写入二进制图片数据
        sku_img_path = os.path.join(abs_path, file_name)
        with open(sku_img_path, 'wb')as f:
            f.write(file.file.read())

        return Response({
            'code': 200,
            'static_path': static_path,
            'msg': '上传图片成功'
        })


# 商品图片的视图集
class SKUImageViewSet(ModelViewSet):
    queryset = SKUImage.objects.all()
    serializer_class = SKUImage_Serializer
    lookup_url_kwarg = 'pk'
    lookup_field = 'pk'
    pagination_class = Page

    # 重写方法 不允许重复添加
    def create(self, request, *args, **kwargs):
        # 1 获取前端数据
        sku_id = request.data.get('sku')
        image = request.data.get('image')

        # 2  判断商品图片是否已添加
        res = SKUImage.objects.filter(sku_id=sku_id, image=image)
        if res:  # 存在 已添加
            return Response({'code':400, 'msg': '该商品已经添加过该图片'})
        # 3  未添加 添加图片
        try:    #不存在 未添加
            SKUImage.objects.create(sku_id=sku_id, image=image)
            return Response({'msg': '添加图片成功'}, status=201)
        except:
            return Response({'msg': '添加图片失败'}, status=400)


ak = '74F2GCXwNJ2c9fgiD3ufHUUDXUrSdgNXW6kmIrXY'
sk = 'LqiDv9FZT8oLhDMHrLWwR-HP1vOoEguyQWUQlmNz'
# 生成七牛云的token
class QiniuToken(APIView):
    def get(self, request):
        # 生成七牛云的token
        token = self.gen_token()
        return Response({'code': 200, 'token': token})

# Auth(ak, sk)

    @staticmethod
    def gen_token():
        # 实例化对象
        q = Auth(ak, sk)
        # 要上传的空间，你的存储空间
        bucket_name = 'luoting'
        # 生成上传 Token
        token = q.upload_token(bucket_name)
        return token









